package main

import (
	"context"
	"fmt"
	"net/http"
	"os"
	"runtime"
	"sync"
	"time"
)

// APIService结构体用于表示API服务相关信息和操作
type APIService struct {
	server    *http.Server
	status    string
	mu        sync.Mutex
	ctx       context.Context
	ctxCancel context.CancelFunc
}

// Start函数用于启动API服务
func (s *APIService) Start() error {
	s.server = &http.Server{
		Addr: ":8080",
		Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			w.Write([]byte("Hello from API Service"))
		}),
	}

	var wg sync.WaitGroup
	wg.Add(1)

	go func() {
		defer wg.Done()
		if err := s.server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			s.SetStatus("启动失败")
			fmt.Printf("启动API服务出错: %v\n", err)
		}
	}()

	wg.Wait()

	return nil
}

// GetStatus函数用于获取API服务的状态
func (s *APIService) GetStatus() string {
	s.mu.Lock()
	defer s.mu.Unlock()
	return s.status
}

// SetStatus函数用于设置API服务的状态
func (s *APIService) SetStatus(status string) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.status = status
}

// 全局变量用于存储API服务实例
var apiService *APIService

// startAPIService函数用于在协程中启动API服务，并设置相关上下文
func startAPIService(ctx context.Context) {
	apiService = &APIService{}
	apiService.ctx, apiService.ctxCancel = context.WithCancel(ctx)
	apiService.SetStatus("启动中")

	go func() {
		defer func() {
			if r := recover(); r != nil {
				apiService.SetStatus("运行时出错，已停止")
				fmt.Printf("API服务运行时出现异常: %v\n", r)
			}
		}()

		for {
			if err := apiService.Start(); err != nil {
				apiService.SetStatus("启动失败")
				return
			}
			apiService.SetStatus("已启动")

			<-apiService.ctx.Done()
			apiService.server.Close()
			apiService.SetStatus("已停止")

			// 等待一段时间后尝试重新启动
			time.Sleep(3 * time.Second)
		}
	}()
}

// getAllGoroutineStatus函数用于获取所有goroutine的状态，这里简单返回数量
func getAllGoroutineStatus() int {
	return runtime.NumGoroutine()
}

func main() {
	if len(os.Args) != 3 || os.Args[1] != "start" || os.Args[2] != "api" {
		fmt.Println("用法: engine start api")
		return
	}

	ctx := context.Background()

	// 启动协程来启动API服务
	startAPIService(ctx)

	// 定期检查API服务状态和goroutine数量
	ticker := time.NewTicker(5 * time.Second)
	defer ticker.Stop()

	for range ticker.C {
		// 获取所有goroutine状态
		goroutineStatus := getAllGoroutineStatus()
		fmt.Printf("当前goroutine数量: %d\n", goroutineStatus)

		// 获取API服务状态并打印
		if apiService != nil {
			fmt.Printf("API服务状态: %s\n", apiService.GetStatus())
		}

		// 如果API服务未启动且当前goroutine数量小于某个阈值（这里假设为2），尝试重新启动
		if apiService != nil && apiService.GetStatus() != "已启动" && goroutineStatus < 2 {
			apiService.ctxCancel()
			startAPIService(ctx)
		}
	}
}
